
/**
 * Date:2019年6月3日上午11:07:14
 * Copyright (c) 2019, www.bwbroad.com All Rights Reserved.
 *
*/

package com.xue.im.client.handler;

import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import com.xue.im.client.core.IMClientContext;
import com.xue.im.common.IMUtil;
import com.xue.im.common.IMUtil.MessageType;
import com.xue.im.common.vo.Message;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

/**
 * Description: 客户端心跳检查请求 <br/>
 * Date: 2019年6月3日 上午11:07:14 <br/>
 * 
 * @author xuejianxin
 */
public class HeartBeatRequestHandler extends ChannelInboundHandlerAdapter {

	private volatile ScheduledFuture<?> heartBeat;

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		Message message = (Message) msg;
		// 登录成功,判断是否握手响应,主动发送心跳消息
		if (IMUtil.checkMessageType(message, MessageType.LOGIN_RESP)) {
			heartBeat = ctx.executor().scheduleAtFixedRate(new HeartBeatRequestHandler.HeartBeatTask(ctx), 0, 5,
					TimeUnit.SECONDS);
			// 接收并处理消息
			IMClientContext.get().receiveMessage(message);
		} else if (IMUtil.checkMessageType(message, MessageType.HEARTBEAT_RESP)) {
			// 心跳响应消息
		} else {
			ctx.fireChannelRead(msg);
		}
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		if (null != heartBeat) {// 有异常的时候撤销心跳请求
			heartBeat.cancel(true);
			heartBeat = null;
		}
		ctx.fireExceptionCaught(cause);
	}

	// 心跳任务
	private class HeartBeatTask implements Runnable {
		private final ChannelHandlerContext ctx;

		public HeartBeatTask(ChannelHandlerContext ctx) {
			this.ctx = ctx;
		}

		@Override
		public void run() {
			//// 构建心跳请求
			Message heartBeat = IMUtil.buildMessage(MessageType.HEARTBEAT_REQ);
			// System.out.println("***client send heart beat->" + heartBeat);
			ctx.writeAndFlush(heartBeat);
		}

	}

}
